using System;
using System.ComponentModel;
using PropertyExpression.Common;

namespace PropertyExpression.ReactiveRelation
{
    public static class CalcExecutorExtensions
    {
        public static ICalcInitiator<TEntity> CreateAndCoupleEntity<TEntity>(
            this ICalcExecutor calcExecutor)
            where TEntity : new()
        {
            return CreateEntity<TEntity>(calcExecutor).Couple(calcExecutor);
        }

        public static TEntity CreateEntity<TEntity>(this ICalcExecutor calcExecutor)
            where TEntity : new()
        {
            var result = new TEntity();
            calcExecutor.CalculateProperties(result);
            return result;
        }

        public static void RegisterEntity<TEntity>(this ICalcExecutor calcExecutor, TEntity entity) 
            where TEntity : INotifyPropertyChanged, INotifyPropertyChanging
        {
            entity.ProcessPropertyChanged(
                (sender, propertyChangedEventArgs, previousValue) =>
                    {
                        Func<string> propertyNameFunc = () => propertyChangedEventArgs.PropertyName;
                        calcExecutor.Calculate(
                            sender,
                            propertyNameFunc,
                            previousValue,
                            () => new OneToManyCollectionNewItemProcessor(
                                      () => new OneToManyCollectionNewItemProvider(
                                                () => sender,
                                                propertyNameFunc,
                                                () => previousValue
                                                )
                                                .AsOptionalResult()
                                      )
                            );
                    }
                );
        }
    }
}